﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;

namespace Tensop.Net.Client
{
    public class TcpClient
    {
        IPEndPoint                  remote;
        IPEndPoint                  local;
        Socket                      socket;
        SocketAsyncEventArgs        read;
        SocketAsyncEventArgs        send;
        SocketAsyncEventArgs        connect;

        List<byte>                  RecvBuffer;
        List<byte>                  SendBuffer;

        byte[]                      ReadBuffer;
        bool                        connected;


        public bool Connected { get => connected; }

        public TcpClient():this(AddressFamily.InterNetwork)
        {

        }
        public TcpClient(AddressFamily af)
        {
            socket = new Socket( af, SocketType.Stream, ProtocolType.Tcp );
            local = new IPEndPoint( FindIPAddress(af), 0 );
            socket.Bind( local );
            read = new SocketAsyncEventArgs();
            send = new SocketAsyncEventArgs();
            ReadBuffer = new byte[65536];
            RecvBuffer = new List<byte>( 65536 );
            SendBuffer = new List<byte>();
        }

        private IPAddress FindIPAddress(AddressFamily af)
        {
            var name = Dns.GetHostName();
            var ips = Dns.GetHostAddresses( name );
            var e = from el in ips where el.AddressFamily == af select el;
            return e.First();
        }

        public void Connect(IPEndPoint remote)
        {
            this.remote = remote;
            if ( connect != null )
                connect.Dispose();
            connect = null;
            connect = new SocketAsyncEventArgs() { RemoteEndPoint = remote };
            if ( socket.ConnectAsync( connect ) )
            {
                Task t = new Task( () =>
                {
                    socket.Connect( remote );
                    FinishConnect();
                } );
                t.Start();
            }
        }

        private void FinishConnect()
        {
            connected = true;
        }

        public void Send(byte[] data)
        {

        }

        public void Stop()
        {

        }

        private void IO_Completed(object sender,SocketAsyncEventArgs e)
        {
            switch ( e.LastOperation )
            {
                case SocketAsyncOperation.Connect:
                    FinishConnect();
                    break;
                case SocketAsyncOperation.Receive:
                    break;
                case SocketAsyncOperation.Send:
                    break;
                case SocketAsyncOperation.Disconnect:
                    break;
            }

        }
    }
}
